package com.eling.elcms.travel.service.impl;

import com.eling.elcms.basedoc.model.*;
import com.eling.elcms.basedoc.service.IBusinessMessageManager;
import com.eling.elcms.basedoc.service.IRoomTypeManager;
import com.eling.elcms.core.exception.BusinessException;
import com.eling.elcms.core.service.impl.GenericManagerImpl;
import com.eling.elcms.core.util.PropertyUtils;
import com.eling.elcms.travel.dao.IPlanItemGroupDao;
import com.eling.elcms.travel.model.*;
import com.eling.elcms.travel.model.CheckInImplement.CheckStatus;
import com.eling.elcms.travel.model.CheckInImplement.DataSource;
import com.eling.elcms.travel.model.RoomRegister.CheckInType;
import com.eling.elcms.travel.model.RoomRegister.RoomStatus;
import com.eling.elcms.travel.model.view.AdjustGroupView;
import com.eling.elcms.travel.model.view.PlanItemGView;
import com.eling.elcms.travel.model.view.PlanItemGroupView;
import com.eling.elcms.travel.model.view.RoomStatisticsView;
import com.eling.elcms.travel.service.*;
import com.eling.elcms.travel.util.DateHandlerUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class PlanItemGroupManagerImpl extends GenericManagerImpl<PlanItemGroup, Long> implements IPlanItemGroupManager {

	IPlanItemGroupDao planItemGroupDao;

	@Autowired
	private IRoomTypeManager roomtypeM;
	@Autowired
	private ISignUpRoomTypeCountManager signUpRoomTypeCountM;
	@Autowired
	private ISignUpRegisterManager surManager;
	@Autowired	
	private ISignUpChargeManager sucManager;
	@Autowired
	private IGroupReserveManager groupReserveManager;
	@Autowired
	private IRoomOccupancyManager roomOccupancyManager;
	@Autowired
	private INonMemberGroupManager nonMemGroupManager;
	@Autowired
	private INonMemGroupReserverManager nonMemReserverManager;
	@Autowired
	private INonMemberRegisterManager nonMemRegManager;
	@Autowired
	private ISignUpRefundManager signUpRefundManager;
	@Autowired
	private ICheckInImplementManager ciiManager;
	@Autowired
	private IRoomPersonalInfoManager rpInfoManager;
	@Autowired
	private IRoomStatisticsManager roomStatisticsManager;
	@Autowired
	private ISignUpRoomManager signUpRoomManager;
	@Autowired
	private IRoomRegisterManager roomRegisterManager;
	@Autowired
	private IBusinessMessageManager businessMessageManager;

	@Autowired
	public void setPlanItemGroupDao(IPlanItemGroupDao planItemGroupDao) {
		this.dao = planItemGroupDao;
		this.planItemGroupDao = planItemGroupDao;
	}

	@SuppressWarnings("unchecked")
	@Override
	public AdjustGroupView saveAdjust(AdjustGroupView view) {
		List<RoomRegister> roomRegisterList=view.getRoomRegisterList();
		if (view.getDataSource().equals(DataSource.GroupReserve)) { // 老人团
			if (null == view.getPlanItemGroup().getAdjustTypes()
					|| view.getPlanItemGroup().getAdjustTypes().isEmpty()) {
				throw new BusinessException("未对该团进行调整！");
			}
			PlanItemGroup planItemGroup = planItemGroupDao.get(view.getPlanItemGroup().getPkPlanItemGroup());
			GroupReserve groupReserve = new GroupReserve();
			groupReserve.setPlanItemGroup(planItemGroup);
			List<GroupReserve> grList = groupReserveManager.query(groupReserve);
			if (!grList.isEmpty()) {
				groupReserve = grList.get(0);
				List<Long> pkRoomRegister=groupReserve.getRoomRegisters().stream().map(a->a.getPkRoomRegister()).collect(Collectors.toList());//原有数据
				List<Long> pkRoomRegisters=roomRegisterList.stream().map(a->a.getPkRoomRegister()).collect(Collectors.toList());//现有数据
				List<Long> pkList=(List<Long>)CollectionUtils.subtract(pkRoomRegister, pkRoomRegisters);
				List<RoomRegister> roomList=new ArrayList<RoomRegister>();
				if(pkList.size()>0){
					RoomRegister room=new RoomRegister();
					PropertyUtils.setProperty(room, "pkRoomRegisterIn", pkList);
					roomList=roomRegisterManager.query(room);
				}
				for(RoomRegister room:roomList){
					groupReserveManager.rid(room, groupReserve);
				}
				List<RoomRegister> list=roomRegisterList.stream().filter(a->a.getPkRoomRegister()==null).collect(Collectors.toList());
				//保存房间登记
				for(int i=0;i<list.size();i++){
					groupReserveManager.saveRoom(groupReserve, list.get(i).getRoom());
				}
				if (view.getAffectRoomType() && reserveRoomsByMem(view, groupReserve)) {
					throw new BusinessException("调整时间段内预约的房间数量不足，请重新预约！");
				}
				// 预约阶段保存入住日期和开始日期
				groupReserve.setCheckInDate(view.getPlanItemGroup().getPlanItem().getStartDate());
				groupReserve.setCheckOutDate(view.getPlanItemGroup().getPlanItem().getEndDate());
				groupReserveManager.save(groupReserve);
			} else {
				// 报名阶段保存开始日期和结束日期
				planItemGroup.getPlanItem().setStartDate(view.getPlanItemGroup().getPlanItem().getStartDate());
				planItemGroup.getPlanItem().setEndDate(view.getPlanItemGroup().getPlanItem().getEndDate());
			}
			planItemGroup.setIsAdjustment(true);
			planItemGroup.setAdjustDate(new Date());
			planItemGroup.setAdjustTypes(view.getPlanItemGroup().getAdjustTypes());
			// 保存调整后的团状态，不包含人员调整
			planItemGroup = planItemGroupDao.save(planItemGroup);

			// 对人员进行处理
			if (!view.getSignUpList().isEmpty()) {
				for (SignUpRegister surout : view.getSignUpList()) {
					surout.setPlanItemGroup(planItemGroup);
				}

				List<SignUpRegister> signUpList = surManager.save(view.getSignUpList());
				planItemGroup.setSignUps(new HashSet<>(signUpList));

				// 保存调整后的团状态，包含人员调整
				planItemGroup = planItemGroupDao.save(planItemGroup);

				// 推送退费单
				sendRefund(signUpList);
			}
		} else { // 散客团
			if (null == view.getNonMemberGroup().getAdjustTypes()
					|| view.getNonMemberGroup().getAdjustTypes().isEmpty()) {
				throw new BusinessException("未对该团进行调整！");
			}
			NonMemberGroup nonMemberGroup = nonMemGroupManager.get(view.getNonMemberGroup().getPkNonMemberGroup());
			if (view.getAffectRoomType() && reserveRoomTypesByMem(view, nonMemberGroup)) {
				throw new BusinessException("调整后，超出总房源，请和预订员联系确认！");
			}
			nonMemberGroup.setCheckInDate(view.getNonMemberGroup().getCheckInDate());
			nonMemberGroup.setCheckOutDate(view.getNonMemberGroup().getCheckOutDate());
			nonMemberGroup.setAdjustDate(new Date());
			nonMemberGroup.setAdjustTypes(view.getNonMemberGroup().getAdjustTypes());
			nonMemberGroup.setIsAdjustment(true);
			nonMemberGroup = nonMemGroupManager.save(nonMemberGroup);

			// 对报名人员增加业务处理
			if (!view.getSignUpList().isEmpty()) {
				NonMemberRegister nonMemberRegister = new NonMemberRegister();
				// 更新报名信息
				List<SignUpRegister> signUpList = surManager.save(view.getSignUpList());
				List<Long> pkSignUpList = signUpList.stream().map(a -> a.getPkSignUpRegister())
						.collect(Collectors.toList());
				PropertyUtils.setProperty(nonMemberRegister, "signUpRegister.pkSignUpRegisterIn", pkSignUpList);
				// 退团人员
				List<NonMemberRegister> nmrList = nonMemRegManager.query(nonMemberRegister);
				List<NonMemberRegister> nmrInList = new ArrayList<>();
				for (SignUpRegister sur : signUpList) {
					Boolean flag = true;
					for (NonMemberRegister nmr : nmrList) {
						if (nmr.getSignUpRegister().getPkSignUpRegister().equals(sur.getPkSignUpRegister())) {
							flag = false;
							break;
						}
					}
					if (flag) {
						NonMemberRegister nmr = new NonMemberRegister();
						nmr.setNonMemberGroup(nonMemberGroup);
						nmr.setSignUpRegister(sur);
						nmr.setVersion(0);
						nmrInList.add(nmr);
					}
				}
				// 保存所有人员
				if (!nmrInList.isEmpty()) {
					nmrInList = nonMemRegManager.save(nmrInList);
					nmrList.addAll(nmrInList);
					nonMemberGroup.setSignUps(new HashSet<>(nmrList));
					nonMemberGroup = nonMemGroupManager.save(nonMemberGroup);
					sendRoomPerInfoByNoMem(nmrList);
				}
			}
		}

		return view;
	}

	@Override
	public List<PlanItemGroupView> querySignUpRefund(PlanItemGroup cond) {
		List<PlanItemGroupView> pigvList = planItemGroupDao.querySignUpRefund(cond);
		return pigvList;
	}

	private void sendRefund(List<SignUpRegister> signUpList) {
		List<Long> pkSignUpList = signUpList.stream().map(a -> a.getPkSignUpRegister()).collect(Collectors.toList());
		SignUpCharge signUpCharge = new SignUpCharge();
		PropertyUtils.setProperty(signUpCharge, "signUpRegister.pkSignUpRegisterIn", pkSignUpList);
		List<SignUpCharge> sucList = sucManager.query(signUpCharge);
		if (!sucList.isEmpty()) {
			// 推加团收费单,删退团收费单
			List<SignUpCharge> newChargeList = new ArrayList<SignUpCharge>();
			Set<SignUpCharge> removeChargeSet = new HashSet<SignUpCharge>();
			for (SignUpRegister sur : signUpList) {
				Boolean flag = true;
				if (null != sur.getExitGroup() && sur.getExitGroup()) {
					flag = false;
				}
				for (SignUpCharge suc : sucList) {
					if (suc.getSignUpRegister().getPkSignUpRegister().equals(sur.getPkSignUpRegister())) {
						flag = false;
						if (null != sur.getExitGroup() && sur.getExitGroup() && suc.getChargeDate() == null
								&& suc.getPayable() == null) {
							removeChargeSet.add(suc);
						}
					}
				}
				if (flag) {
					SignUpCharge newSaveCharge = new SignUpCharge();
					newSaveCharge.setSignUpRegister(sur);
					newSaveCharge.setVersion(0);
					newChargeList.add(newSaveCharge);
				}
			}
			// 推加团收费单
			if (!newChargeList.isEmpty()) {
				sucManager.save(newChargeList);
				businessMessageManager.saveBusinessMessage(new BusinessMessage(TargetType.Role,TaskType.SignUpCharge,signUpList.get(0).getPlanItemGroup().getPkPlanItemGroup()));
			}
			// 删退团收费单
			if (!removeChargeSet.isEmpty()) {
				sucManager.remove(new ArrayList<>(removeChargeSet));
			}

			// 推退费单
			List<SignUpRefund> suRefundList = new ArrayList<>();
			List<Long> pkSUCList = sucList.stream().map(a -> a.getPkSignUpCharge()).collect(Collectors.toList());
			SignUpRefund surCond = new SignUpRefund();
			PropertyUtils.setProperty(surCond, "signUpCharge.pkSignUpChargeIn", pkSUCList);
			List<SignUpRefund> surList = signUpRefundManager.query(surCond);
			for (SignUpCharge suc : sucList) {
				Boolean flag = true;
				if (null == suc.getSignUpRegister().getExitGroup() || !suc.getSignUpRegister().getExitGroup()
						|| suc.getPayable() == null || suc.getOperator() == null || suc.getChargeDate() == null) {
					flag = false;
				}
				for (SignUpRefund sur : surList) {
					if ((null == suc.getSignUpRegister().getExitGroup() || !suc.getSignUpRegister().getExitGroup())
							|| sur.getSignUpCharge().getPkSignUpCharge().equals(suc.getPkSignUpCharge())) {
						flag = false;
						break;
					}
				}
				if (flag) {
					SignUpRefund suRefund = new SignUpRefund();
					suRefund.setSignUpCharge(suc);
					suRefund.setVersion(0);
					suRefundList.add(suRefund);
				}
			}
			if (!suRefundList.isEmpty()) {
				signUpRefundManager.save(suRefundList);
				businessMessageManager.saveBusinessMessage(new BusinessMessage(TargetType.Role,TaskType.SignUpRefund,signUpList.get(0).getPlanItemGroup().getPkPlanItemGroup()));
			}
		}

		// 如果该团已在入住准备中落实，则推送人员信息，需要到入住登记中登记新增人员的房间登记信息
		sendRoomPerInfoByMem(signUpList);

	}

	/**
	 * 老人团更新落实单
	 * 
	 * @param signUpList
	 */
	private void sendRoomPerInfoByMem(List<SignUpRegister> signUpList) {
		PlanItemGroup planItemGroup = signUpList.get(0).getPlanItemGroup();
		CheckInImplement checkInImplement = new CheckInImplement();
		PropertyUtils.setProperty(checkInImplement, "groupReserve.planItemGroup.pkPlanItemGroup",
				planItemGroup.getPkPlanItemGroup());
		List<CheckInImplement> ciiList = ciiManager.query(checkInImplement);
		if (!ciiList.isEmpty() && !ciiList.get(0).getStatus().equals(CheckStatus.Initial)) {
			checkInImplement = ciiList.get(0);
			// 获取人与房间的信息
			Set<RoomPersonalInfo> rpiSet = checkInImplement.getRoomPersonalInfos();
			// 新增人员与房间信息
			Set<RoomPersonalInfo> newRpiSet = new HashSet<>();
			// 删除人员与房间信息
			Set<RoomPersonalInfo> removeRpiSet = new HashSet<>();

			Set<Room> roomSet = new HashSet<>();
			for (SignUpRegister sur : signUpList) {
				Boolean flag = true;
				if (null != sur.getExitGroup() && sur.getExitGroup()) {
					flag = false;
				}
				for (RoomPersonalInfo rpi : rpiSet) {
					if (rpi.getSignUpRegister().getPkSignUpRegister().equals(sur.getPkSignUpRegister())) {
						if (!flag) {
							if (rpi.getRoomRegister().getRoom()!=null) {
								roomSet.add(rpi.getRoomRegister().getRoom());
							}
							removeRpiSet.add(rpi);
						}
						flag = false;
						break;
					}
				}
				if (flag) {
					RoomRegister roomRegister = new RoomRegister();
					roomRegister.setStatus(CheckStatus.Pending);
					roomRegister.setRoomStatus(RoomStatus.NoCheckIn);
					roomRegister.setCheckInType(CheckInType.Member);
					roomRegister.setVersion(0);
					RoomPersonalInfo newRpi = new RoomPersonalInfo();
					newRpi.setSignUpRegister(sur);
					newRpi.setRoomRegister(roomRegister);
					newRpi.setCheckInImplement(checkInImplement);
					newRpi.setCheckIn(!flag);
					newRpi.setVersion(0);
					newRpiSet.add(newRpi);
				}
			}

			// 删除退团人员与房间信息
			if (!removeRpiSet.isEmpty()) {
				rpiSet.removeAll(new ArrayList<>(removeRpiSet));
				rpInfoManager.remove(new ArrayList<>(removeRpiSet));
				// 删除同房间退团人员的房间信息
				if (!roomSet.isEmpty()) {
					List<Long> pkRoomList = new ArrayList<>();
					for (Room rm : roomSet) {
						Boolean flag = true;
						for (RoomPersonalInfo rpi : rpiSet) {
							if ((null == rpi.getSignUpRegister().getExitGroup()
									|| !rpi.getSignUpRegister().getExitGroup())
									&& rpi.getRoomRegister().getRoom() != null
									&& rpi.getRoomRegister().getRoom().getPkRoom().equals(rm.getPkRoom())) {
								flag = false;
							}
						}
						if (flag) {
							pkRoomList.add(rm.getPkRoom());
						}
					}
					// 删除房间占用数据
					if (!pkRoomList.isEmpty()) {
						roomOccupancyManager.removeRoomOccup(planItemGroup, pkRoomList);
					}
				}
			}

			// 新增人员与房间信息
			if (!newRpiSet.isEmpty()) {
				List<RoomPersonalInfo> newRpiList = rpInfoManager.save(new ArrayList<>(newRpiSet));
				rpiSet.addAll(newRpiList);
			}

			checkInImplement.setRoomPersonalInfos(rpiSet);
			// 回写落实单状态
			if(checkInImplement.getStatus().equals(CheckStatus.Confirmed)){
				// 老人团的落实单状态为已落实时还原状态为准备中
				checkInImplement.setRoomStatus(CheckStatus.Pending);
				
//				if(checkInImplement.getCheckInCar() != null 
//						&& checkInImplement.getCheckInCar().getStatus().equals(CheckStatus.Pended)){
//					checkInImplement.getCheckInCar().setStatus(CheckStatus.Pending);
//				}
				Set<CheckInCar> checkInCar = checkInImplement.getCheckInCar();
				if(checkInCar!=null && !checkInCar.isEmpty()){
					for (CheckInCar car : checkInCar) {
						if(car.getStatus().equals(CheckStatus.Pended)){
							car.setStatus(CheckStatus.Pending);
						}
					}
				}
				
				if(checkInImplement.getCheckInDinner() != null 
						&& checkInImplement.getCheckInDinner().getStatus().equals(CheckStatus.Pended)){
					checkInImplement.getCheckInDinner().setStatus(CheckStatus.Pending);
				}
				checkInImplement.setStatus(CheckStatus.Doing);
				List<RoomRegister> roomRegisterList = rpiSet.stream().map(a->a.getRoomRegister()).collect(Collectors.toList());
				if(!roomRegisterList.isEmpty()){
					for(RoomRegister rr : roomRegisterList){
						rr.setStatus(CheckStatus.Pending);
					}
					roomRegisterManager.save(roomRegisterList);
				}
			}
			checkInImplement = ciiManager.save(checkInImplement);
		}
	}

	/**
	 * 散客团更新落实单
	 * 
	 * @param signUpList
	 */
	private void sendRoomPerInfoByNoMem(List<NonMemberRegister> nmrList) {
		NonMemberGroup nonMemberGroup = nmrList.get(0).getNonMemberGroup();
		CheckInImplement checkInImplement = new CheckInImplement();
		PropertyUtils.setProperty(checkInImplement, "nonMemGroupReserve.nonMemberGroup.pkNonMemberGroup",
				nonMemberGroup.getPkNonMemberGroup());
		List<CheckInImplement> ciiList = ciiManager.query(checkInImplement);
		if (!ciiList.isEmpty() && !ciiList.get(0).getStatus().equals(CheckStatus.Initial)) {
			checkInImplement = ciiList.get(0);
			// 获取人与房间的信息
			Set<RoomPersonalInfo> rpiSet = checkInImplement.getRoomPersonalInfos();
			// 新增人员与房间信息
			Set<RoomPersonalInfo> newRpiSet = new HashSet<>();
			// 删除人员与房间信息
			Set<RoomPersonalInfo> removeRpiSet = new HashSet<>();
			for (NonMemberRegister nmr : nmrList) {
				Boolean flag = true;
				if (null != nmr.getSignUpRegister().getExitGroup() && nmr.getSignUpRegister().getExitGroup()) {
					flag = false;
				}
				for (RoomPersonalInfo rpi : rpiSet) {
					if (rpi.getNonMemberRegister().getPkNonMemberRegister().equals(nmr.getPkNonMemberRegister())) {
						if (!flag) {
							removeRpiSet.add(rpi);
						}
						flag = false;
						break;
					}
				}
				if (flag) {
					RoomRegister roomRegister = new RoomRegister();
					roomRegister.setStatus(CheckStatus.Pending);
					roomRegister.setRoomStatus(RoomStatus.NoCheckIn);
					roomRegister.setCheckInType(CheckInType.Member);
					roomRegister.setVersion(0);
					RoomPersonalInfo newRpi = new RoomPersonalInfo();
					newRpi.setNonMemberRegister(nmr);
					newRpi.setRoomRegister(roomRegister);
					newRpi.setCheckInImplement(checkInImplement);
					newRpi.setCheckIn(!flag);
					newRpi.setVersion(0);
					newRpiSet.add(newRpi);
				}
			}
			// 删除退团人员与房间信息
			if (!removeRpiSet.isEmpty()) {
				rpiSet.removeAll(new ArrayList<>(removeRpiSet));
				rpInfoManager.remove(new ArrayList<>(removeRpiSet));
			}

			// 新增人员与房间信息
			if (!newRpiSet.isEmpty()) {
				List<RoomPersonalInfo> newRpiList = rpInfoManager.save(new ArrayList<>(newRpiSet));
				rpiSet.addAll(newRpiList);
			}

			checkInImplement.setRoomPersonalInfos(rpiSet);
			// 回写落实单状态
			if(checkInImplement.getStatus().equals(CheckStatus.Confirmed)){
				// 散客团的落实单状态为已落实时还原状态为准备中
				checkInImplement.setRoomStatus(CheckStatus.Pending);
				
//				if(checkInImplement.getCheckInCar() != null 
//						&& checkInImplement.getCheckInCar().getStatus().equals(CheckStatus.Pended)){
//					checkInImplement.getCheckInCar().setStatus(CheckStatus.Pending);
//				}
				
				Set<CheckInCar> checkInCar = checkInImplement.getCheckInCar();
				if(checkInCar!=null && !checkInCar.isEmpty()){
					for (CheckInCar car : checkInCar) {
						if(car.getStatus().equals(CheckStatus.Pended)){
							car.setStatus(CheckStatus.Pending);
						}
					}
				}
				
				if(checkInImplement.getCheckInDinner() != null 
						&& checkInImplement.getCheckInDinner().getStatus().equals(CheckStatus.Pended)){
					checkInImplement.getCheckInDinner().setStatus(CheckStatus.Pending);
				}
				checkInImplement.setStatus(CheckStatus.Doing);
				Set<SignUpRoom> signUpRmSet = checkInImplement.getNonMemGroupReserve().getSignUpRooms();
				if(!signUpRmSet.isEmpty()){
					for(SignUpRoom sur : signUpRmSet){
						sur.setRoomStatus(CheckStatus.Pending);
					}
					signUpRoomManager.save(new ArrayList<>(signUpRmSet));
				}
			}
			checkInImplement = ciiManager.save(checkInImplement);
		}
	}

	/**
	 * 老人团整团取消
	 * 
	 * @param cond
	 * @author zhoulin
	 */
	@Override
	public PlanItemGroup cancelGroup(PlanItemGroup cond) {
		cond = save(cond);
		// 查询报名人员
		SignUpRegister signUpRegister = new SignUpRegister();
		signUpRegister.setPlanItemGroup(cond);
		List<SignUpRegister> signUpRegisters = surManager.query(signUpRegister);

		// 修改所有报名人员属性为退团
		for (SignUpRegister sur : signUpRegisters) {
			sur.setExitGroup(true);
		}
		signUpRegisters = surManager.save(signUpRegisters);

		// 发送退费单
		sendRefund(signUpRegisters);

		// 删除房间占用数据
		roomOccupancyManager.removeRoomOccup(cond);

		return cond;
	}

	/**
	 * TODO 代码待优化 老人团房间状态回写
	 * 
	 * @param view
	 * @param groupReserve
	 * @return
	 * @author zhoulin
	 */
	private boolean reserveRoomsByMem(AdjustGroupView view, GroupReserve groupReserve) {
		List<Room> roomList = new ArrayList<>();
		List<Long> pkRoomList = new ArrayList<>();
		if (!groupReserve.getRoomRegisters().isEmpty()) {
			for (RoomRegister rr : groupReserve.getRoomRegisters()) {
				if (null != rr.getRoom()) {
					roomList.add(rr.getRoom());
					pkRoomList.add(rr.getRoom().getPkRoom());
				}
			}

			// 预约房间判空
			if (!roomList.isEmpty()) {
				// 调整后影响房间预约时间段
				Date newStartDate = null;
				Date newEndDate = null;

				// 调整后日期不交差X<Y<=A<B,A<B<=X<Y
				if (0 == adjustTimeComparison(groupReserve.getCheckInDate(), groupReserve.getCheckOutDate(),
						view.getPlanItemGroup().getPlanItem().getStartDate(),
						view.getPlanItemGroup().getPlanItem().getEndDate())) {
					newStartDate = view.getPlanItemGroup().getPlanItem().getStartDate();
					newEndDate = view.getPlanItemGroup().getPlanItem().getEndDate();
				}
				// 调整后日期交差X<=A<Y<=B
				if (1 == adjustTimeComparison(groupReserve.getCheckInDate(), groupReserve.getCheckOutDate(),
						view.getPlanItemGroup().getPlanItem().getStartDate(),
						view.getPlanItemGroup().getPlanItem().getEndDate())) {
					newStartDate = view.getPlanItemGroup().getPlanItem().getStartDate();
					newEndDate = groupReserve.getCheckInDate();
				}
				// 调整后日期交差A<=X<B<=Y
				if (2 == adjustTimeComparison(groupReserve.getCheckInDate(), groupReserve.getCheckOutDate(),
						view.getPlanItemGroup().getPlanItem().getStartDate(),
						view.getPlanItemGroup().getPlanItem().getEndDate())) {
					newStartDate = groupReserve.getCheckOutDate();
					newEndDate = view.getPlanItemGroup().getPlanItem().getEndDate();
				}
				// 调整后日期交差A<=X<Y<=B,此情况不会新增房间预约
				if (3 == adjustTimeComparison(groupReserve.getCheckInDate(), groupReserve.getCheckOutDate(),
						view.getPlanItemGroup().getPlanItem().getStartDate(),
						view.getPlanItemGroup().getPlanItem().getEndDate())) {
				}

				if (newStartDate != null && newEndDate != null) {
					RoomOccupancy roomOccupancy = new RoomOccupancy();
					PropertyUtils.setProperty(roomOccupancy, "room.pkRoomIn", pkRoomList);
					PropertyUtils.setProperty(roomOccupancy, "occupyDate", newStartDate);
					PropertyUtils.setProperty(roomOccupancy, "occupyDateEnd", newEndDate);
					List<RoomOccupancy> rOccupList = roomOccupancyManager.query(roomOccupancy);
					// 调整时间段内，房间被占用
					if (!rOccupList.isEmpty()) {
						for (RoomOccupancy ro : rOccupList) {
							if (!ro.getPlanItemGroup().getPkPlanItemGroup()
									.equals(groupReserve.getPlanItemGroup().getPkPlanItemGroup())) {
								return true;
							}
						}
					}
				}
				roomOccupancyManager.removeRoomOccup(groupReserve.getPlanItemGroup());

				Set<Date> dateSet = DateHandlerUtil.timeOfDaysByTwoDate(
						view.getPlanItemGroup().getPlanItem().getStartDate(),
						view.getPlanItemGroup().getPlanItem().getEndDate());
				roomOccupancyManager.newRoomOccup(groupReserve.getPlanItemGroup(), roomList, dateSet);

			}
		}

		return false;
	}

	/**
	 * 散客团调整查询房型是否可用
	 * 
	 * @param view
	 * @param nonMemberGroup
	 * @return
	 * @author zhoulin
	 */
	private Boolean reserveRoomTypesByMem(AdjustGroupView view, NonMemberGroup nonMemberGroup) {

		// 计算调整后影响房型预约的天数
		int i = 0;

		List<RoomStatisticsView> allList = new ArrayList<>();
		// 调整后：1、开始日期大于原结束日期(B<=X)；2、结束日期小于原开始日期(Y<=A)
		if (nonMemberGroup.getCheckOutDate().getTime() <= view.getNonMemberGroup().getCheckInDate().getTime()
				|| nonMemberGroup.getCheckInDate().getTime() >= view.getNonMemberGroup().getCheckOutDate().getTime()) {
			allList.addAll(roomStatisticsManager.queryAllByDate(view.getNonMemberGroup().getCheckInDate(),
					view.getNonMemberGroup().getCheckOutDate(), nonMemberGroup.getServicePoint()));
			i = (int) ((view.getNonMemberGroup().getCheckOutDate().getTime()
					- view.getNonMemberGroup().getCheckInDate().getTime()) / (1000 * 3600 * 24));
		}
		// 调整后日期交差X<=A<Y<=B
		if (view.getNonMemberGroup().getCheckInDate().getTime() <= nonMemberGroup.getCheckInDate().getTime()
				&& view.getNonMemberGroup().getCheckOutDate().getTime() <= nonMemberGroup.getCheckOutDate().getTime()) {
			allList.addAll(roomStatisticsManager.queryAllByDate(view.getNonMemberGroup().getCheckInDate(),
					nonMemberGroup.getCheckInDate(), nonMemberGroup.getServicePoint()));
			i = (int) ((nonMemberGroup.getCheckInDate().getTime() - view.getNonMemberGroup().getCheckInDate().getTime())
					/ (1000 * 3600 * 24));
		}
		// 调整后日期交差A<=X<B<=Y
		if (view.getNonMemberGroup().getCheckInDate().getTime() >= nonMemberGroup.getCheckInDate().getTime()
				&& view.getNonMemberGroup().getCheckOutDate().getTime() >= nonMemberGroup.getCheckOutDate().getTime()) {
			allList.addAll(roomStatisticsManager.queryAllByDate(nonMemberGroup.getCheckOutDate(),
					view.getNonMemberGroup().getCheckOutDate(), nonMemberGroup.getServicePoint()));
			i = (int) ((view.getNonMemberGroup().getCheckOutDate().getTime()
					- nonMemberGroup.getCheckOutDate().getTime()) / (1000 * 3600 * 24));
		}
		// 调整后日期交差A<=X<Y<=B
		if (view.getNonMemberGroup().getCheckInDate().getTime() <= nonMemberGroup.getCheckInDate().getTime()
				&& view.getNonMemberGroup().getCheckOutDate().getTime() >= nonMemberGroup.getCheckOutDate().getTime()) {
			allList.addAll(roomStatisticsManager.queryAllByDate(view.getNonMemberGroup().getCheckInDate(),
					nonMemberGroup.getCheckInDate(), nonMemberGroup.getServicePoint()));
			i = (int) ((nonMemberGroup.getCheckInDate().getTime() - view.getNonMemberGroup().getCheckInDate().getTime())
					/ (1000 * 3600 * 24));
		}

		NonMemGroupReserve nonMemGroupReserve = new NonMemGroupReserve();
		nonMemGroupReserve.setNonMemberGroup(nonMemberGroup);
		List<NonMemGroupReserve> nmgrList = nonMemReserverManager.query(nonMemGroupReserve);
		if (!nmgrList.isEmpty()) {
			nonMemGroupReserve = nmgrList.get(0);
			Set<SignUpRoom> signUpRoomSet = nonMemGroupReserve.getSignUpRooms();
			for (SignUpRoom sur : signUpRoomSet) {
				for (RoomStatisticsView rsv : allList) {
					// 如果统计中的房型与预约的相匹配
					if (sur.getRoomType().getPkRoomType().equals(rsv.getPkRoomType())) {
						// 预约该房型的数量
						Integer reserveCount = sur.getCount();
						if (countRoomTypeNumber(i, rsv, reserveCount)) {
							return true;
						}
					}
				}
			}
		}

		return false;
	}

	private Boolean countRoomTypeNumber(int i, RoomStatisticsView rsv, Integer reserveCount) {
		// 现有该房型总数量
		Integer existenceCount = rsv.getRoomcount();

		List<Integer> roomNumList = new ArrayList<>();
		roomNumList.add(rsv.getDayOne());
		roomNumList.add(rsv.getDayTwo());
		roomNumList.add(rsv.getDayThree());
		roomNumList.add(rsv.getDayFour());
		roomNumList.add(rsv.getDayFive());
		roomNumList.add(rsv.getDaySix());
		roomNumList.add(rsv.getDaySeven());
		roomNumList.add(rsv.getDayEight());
		roomNumList.add(rsv.getDayNine());
		roomNumList.add(rsv.getDayTen());
		roomNumList.add(rsv.getDayEleven());
		roomNumList.add(rsv.getDayTwelve());
		roomNumList.add(rsv.getDayThirdteen());
		roomNumList.add(rsv.getDayFourteen());
		roomNumList.add(rsv.getDayFifteen());

		// 调整后影响房间预约的天数大于15不考虑
		int k = 0;
		if (i > 15) {
			k = 15;
		} else {
			k = i;
		}

		// 比较预约数量+单日数量是否大于现有该房型总数量（不考虑第一天）
		for (int j = 1; j < k; j++) {
			if (reserveCount + roomNumList.get(j) > existenceCount) {
				return true;
			}
		}
		return false;
	}

	@Override
	public Long queryPlanItemGPk(Long pkGroupReserve) {
		return planItemGroupDao.queryPlanItemGPk(pkGroupReserve);
	}

	/**
	 * 比较调整后的日期变化情况
	 * 
	 * @param preStartDate
	 * @param preEndDate
	 * @param adjustStartDate
	 * @param adjustEndDate
	 * @return
	 */
	private int adjustTimeComparison(Date preStartDate, Date preEndDate, Date adjustStartDate, Date adjustEndDate) {
		// 调整后：1、开始日期大于原结束日期(B<=X)；2、结束日期小于原开始日期(Y<=A):return 0
		if (preEndDate.getTime() <= adjustStartDate.getTime() || preStartDate.getTime() >= adjustEndDate.getTime()) {
			return 0;
		}
		// 调整后日期交差X<=A<Y<=B:return 1
		if (adjustStartDate.getTime() <= preStartDate.getTime() && adjustEndDate.getTime() <= preEndDate.getTime()) {
			return 1;
		}
		// 调整后日期交差A<=X<B<=Y:return 2
		if (adjustStartDate.getTime() >= preStartDate.getTime() && adjustEndDate.getTime() >= preEndDate.getTime()) {
			return 2;
		}
		// 调整后日期交差A<=X<Y<=B:return 3
		if (adjustStartDate.getTime() <= preStartDate.getTime() && adjustEndDate.getTime() >= preEndDate.getTime()) {
			return 3;
		}
		return 4;
	}

	@Override
	public PlanItemGroup saveRoomType(PlanItemGView cond) {
		
		PlanItemGroup planItemGroup = new PlanItemGroup();
		planItemGroup.setPkPlanItemGroup(cond.getPkPlanItemGroup());
		//根据pk查询该planItemGroup
		List<PlanItemGroup> planItemGroups = query(planItemGroup);
		if(planItemGroups != null && !planItemGroups.isEmpty()){
			planItemGroup = planItemGroups.get(0);
			if(cond.getSignUpRoomTypeCounts() != null){
				for (int i = 0; i < cond.getSignUpRoomTypeCounts().size(); i++) {
					RoomType roomType = cond.getSignUpRoomTypeCounts().get(i).getRoomType();
					roomType = roomtypeM.query(roomType).get(0);
					cond.getSignUpRoomTypeCounts().get(i).setRoomType(roomType);
				}
			}
			List<SignUpRoomTypeCount> signUpRoomTypeCounts = signUpRoomTypeCountM.save(cond.getSignUpRoomTypeCounts());
			Set<SignUpRoomTypeCount> signUpRoomTypeCountSet = new HashSet<>(signUpRoomTypeCounts);
			planItemGroup.setSignUpRoomTypeCounts(signUpRoomTypeCountSet);
			planItemGroup.setVersion(cond.getVersion());
			planItemGroup = save(planItemGroup);
		}
		return planItemGroup;
	}
}
